home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Magazine / C_Tutorial / Part-14 / exall2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-04  |  7.7 KB  |  321 lines

  1. #include<dos/dos.h>
  2. #include<dos/exall.h>
  3. #include<exec/libraries.h>
  4. #include<exec/memory.h>
  5. #include<graphics/text.h>
  6. #include<intuition/intuition.h>
  7. #include<intuition/screens.h>
  8. #include<libraries/gadtools.h>
  9. #include<utility/tagitem.h>
  10.  
  11. #include<string.h>
  12. #include<stdio.h>
  13. #include<stdlib.h>
  14.  
  15. #include<clib/alib_protos.h>
  16. #include<clib/dos_protos.h>
  17. #include<clib/exec_protos.h>
  18. #include<clib/gadtools_protos.h>
  19. #include<clib/intuition_protos.h>
  20.  
  21. /* The library base global variables */
  22. struct Library* DosBase;
  23. struct Library* GadToolsBase;
  24. struct Library* IntuitionBase;
  25.  
  26. /* Need to give prototypes for our functions */
  27. void handleIDCMP(struct Window*);
  28. void setupWindow(void);
  29. void createWindow(struct Gadget*);
  30.  
  31. void addNode(char*);
  32. void freeNode(struct Node*);
  33. void freeList(void);
  34. int  fillList(char*);
  35. void sortList(void);
  36.  
  37. #define MYFONTSIZE        (8)
  38.  
  39. /* Some constants for the size of the window */
  40. #define MYWIN_WIDTH        (200)
  41. #define MYWIN_HEIGHT    (200)
  42.  
  43. /* Some constants for the position and size of our gadget */
  44. #define MYGAD_LEFT        (10)
  45. #define MYGAD_TOP            (10+MYFONTSIZE)
  46. #define MYGAD_WIDTH        (MYWIN_WIDTH-MYGAD_LEFT*2)
  47. #define MYGAD_HEIGHT    (MYWIN_HEIGHT-MYGAD_TOP*2+MYFONTSIZE)
  48. #define MYGAD_TEXT        ("Files")
  49. #define MYGAD_ID            (0)
  50.  
  51. /* Initialised structure declaration: describes standard Topaz font */
  52. static struct TextAttr topazFont = { "topaz.font", MYFONTSIZE, 0, 0, };
  53.  
  54. static struct List mylist;
  55. static int mycount = 0;
  56.  
  57. void addNode(char* name)
  58. {
  59.     if(name)
  60.     {
  61.         struct Node* node = AllocVec(sizeof(struct Node), MEMF_PUBLIC | MEMF_CLEAR);
  62.         if(node)
  63.         {
  64.             if(node->ln_Name = AllocVec(strlen(name)+1, MEMF_PUBLIC))
  65.                 strcpy(node->ln_Name, name);
  66.             AddTail(&mylist, node);
  67.             mycount++;
  68.         }
  69.     }
  70. }
  71.  
  72. void freeNode(struct Node* node)
  73. {
  74.     FreeVec(node->ln_Name);
  75.     FreeVec(node);
  76. }
  77.  
  78. void freeList()
  79. {
  80.     struct Node* work;
  81.     struct Node* next = mylist.lh_Head;
  82.     while(next->ln_Succ)
  83.     {
  84.         work = next;
  85.         next = next->ln_Succ;
  86.         freeNode(work);
  87.     }
  88.     mycount = 0;
  89. }
  90.  
  91. #define EABUFF_NUM  (30)
  92. #define EABUFF_SIZE (EABUFF_NUM*sizeof(struct ExAllData))
  93.  
  94. /* Our buffer for ExAll() */
  95. static struct ExAllData EABuff[EABUFF_NUM];
  96.  
  97. int fillList(char* dir)
  98. {
  99.     int success = FALSE;
  100.     /* Get a lock on the directory */
  101.     BPTR lock = Lock(dir, ACCESS_READ);
  102.     if(lock)
  103.     {
  104.         /* Allocate ExAll control object */
  105.         struct ExAllControl* eac = AllocDosObject(DOS_EXALLCONTROL,NULL);
  106.         if(eac)
  107.         {
  108.             int going = TRUE;
  109.             /* Must initialise LastKey to zero before calling ExAll() */
  110.             eac->eac_LastKey = 0;
  111.             /* If we got this far we're OK */
  112.             success = TRUE;
  113.             while(going)
  114.             {
  115.                 /* Fill the buffer with directory entries */
  116.                 going = ExAll(lock, EABuff, EABUFF_SIZE, ED_NAME, eac);
  117.                 /* It's only an error if ExAll() returns FALSE and IoErr() signals */
  118.                 /* something other than running out of directory entries */
  119.                 if(!going)
  120.                     success = (IoErr() == ERROR_NO_MORE_ENTRIES);
  121.                 if(success)
  122.                 {
  123.                     if(eac->eac_Entries != 0)
  124.                     {
  125.                         /* Run through a buffer load of entries */
  126.                         struct ExAllData* ead = EABuff;
  127.                         while(ead)
  128.                         {
  129.                             addNode(ead->ed_Name);
  130.                             ead = ead->ed_Next;
  131.                         }
  132.                     }
  133.                 }
  134.             }
  135.             /* Print an error report if necessary */
  136.             if(!success)
  137.                 PrintFault(IoErr(), "Error");
  138.             FreeDosObject(DOS_EXALLCONTROL,eac);
  139.         }
  140.         else
  141.             printf("Error: could not create ExAll control object\n");
  142.         UnLock(lock);
  143.     }
  144.     else
  145.         printf("Error: could not lock directory \"%s\"\n", dir);
  146.     return success;
  147. }
  148.  
  149. int compareNode(const void* a, const void* b)
  150. {
  151.     struct Node** na = (struct Node**)a;
  152.     struct Node** nb = (struct Node**)b;
  153.     /* Use "strcmp()" if "stricmp()" doesn't work on your compiler */
  154.     return stricmp((*na)->ln_Name, (*nb)->ln_Name);
  155. }
  156.  
  157. void sortList()
  158. {
  159.     if(mycount > 1)
  160.     {
  161.         struct Node** sortarray = malloc(mycount*sizeof(struct Node*));
  162.         if(sortarray)
  163.         {
  164.             /* Copy pointers to the nodes into the array, in order */
  165.             int i = 0;
  166.             struct Node* next = mylist.lh_Head;
  167.             while(next->ln_Succ)
  168.             {
  169.                 sortarray[i++] = next;
  170.                 next = next->ln_Succ;
  171.             }
  172.             /* Sort the array of pointers */
  173.             qsort(sortarray, mycount, sizeof(struct Node*), &compareNode);
  174.             /* Clear the list, then refill it */
  175.             NewList(&mylist);
  176.             for(i=0; i<mycount; i++)
  177.                 AddTail(&mylist, sortarray[i]);
  178.             free(sortarray);
  179.         }
  180.     }
  181. }
  182.  
  183. /* The start of the program */
  184. void main()
  185. {
  186.     /* Open libraries... */
  187.     if(IntuitionBase = OpenLibrary("intuition.library",37))
  188.     {
  189.         if(GadToolsBase = OpenLibrary("gadtools.library",37))
  190.         {
  191.             if(DosBase = OpenLibrary("dos.library",37))
  192.             {
  193.                 /* Now do the real work */
  194.                 NewList(&mylist);
  195.                 if(fillList("sys:"))
  196.                 {
  197.                     sortList();
  198.                     setupWindow();
  199.                 }
  200.                 freeList();
  201.                 CloseLibrary(DosBase);
  202.             }
  203.             else
  204.                 printf("Error: could not open dos.library\n");
  205.             CloseLibrary(GadToolsBase);
  206.         }
  207.         else
  208.             printf("Error: could not open gadtools.library\n");
  209.         CloseLibrary(IntuitionBase);
  210.     }
  211.     else
  212.         printf("Error: could not open intuition.library\n");
  213. }
  214.  
  215. /* Setup the window -- do the GadTools stuff */
  216. void setupWindow()
  217. {
  218.     struct Screen* scr;
  219.     /* We'll copy the visual information for the default public screen */
  220.   /* (usually, this is the Workbench screen) */
  221.     if(scr = LockPubScreen(NULL))
  222.     {
  223.         APTR vinfo;
  224.         /* Get the visual info so GadTools can render the gadgets nicely */
  225.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  226.         {
  227.             struct Gadget* glist = NULL;
  228.             struct Gadget* listgad;
  229.             if(listgad = CreateContext(&glist))
  230.             {
  231.                 struct NewGadget newgad;
  232.                 /* The offsets of our window borders */
  233.                 int offleft = scr->WBorLeft;
  234.                 int offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  235.                 /* Setup our first gadget */
  236.                 newgad.ng_TextAttr         = &topazFont;
  237.                 newgad.ng_VisualInfo     = vinfo;
  238.                 newgad.ng_LeftEdge         = MYGAD_LEFT + offleft;
  239.                 newgad.ng_TopEdge         = MYGAD_TOP + offtop;
  240.                 newgad.ng_Width             = MYGAD_WIDTH;
  241.                 newgad.ng_Height             = MYGAD_HEIGHT;
  242.                 newgad.ng_GadgetText    = MYGAD_TEXT;
  243.                 newgad.ng_GadgetID        = MYGAD_ID;
  244.                 newgad.ng_Flags                = 0;
  245.                 /* Now create it and add it to our list */
  246.                 if(listgad = CreateGadget(LISTVIEW_KIND, listgad, &newgad,
  247.                                                                     GTLV_Labels, &mylist,
  248.                                                                     TAG_DONE))
  249.                     createWindow(glist);
  250.                 else
  251.                     printf("Error: could not create gadget(s)\n");
  252.                 /* Free the gadget */
  253.                 FreeGadgets(glist);
  254.             }
  255.             else
  256.                 printf("Error: could not create GadTools context\n");
  257.             FreeVisualInfo(vinfo);
  258.         }
  259.         else
  260.             printf("Error: could not get visual info\n");
  261.         UnlockPubScreen(NULL, scr);
  262.     }
  263.     else
  264.         printf("Error: could not lock public screen\n");
  265. }
  266.  
  267. /* Actually open the window, in the normal way */
  268. void createWindow(struct Gadget* glist)
  269. {
  270.     struct Window* win;
  271.     /* Open our window */
  272.     if(win = OpenWindowTags(NULL,
  273.                                                     WA_InnerWidth,    MYWIN_WIDTH,
  274.                                                     WA_InnerHeight,    MYWIN_HEIGHT,
  275.                                                     WA_Title,        "Directory List",
  276.                                                     WA_Flags,        WFLG_CLOSEGADGET | WFLG_DRAGBAR,
  277.                                                     WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | LISTVIEWIDCMP,
  278.                                                     WA_Gadgets,    glist,
  279.                                                     TAG_DONE,        0))
  280.     {
  281.         /* Let GadTools refresh its bits of the window */
  282.         GT_RefreshWindow(win, NULL);
  283.         /* Now handle messages */
  284.         handleIDCMP(win);
  285.         CloseWindow(win);
  286.     }
  287.     else
  288.         printf("Error: could not open window\n");
  289. }
  290.  
  291. /* Our message handling code */
  292. void handleIDCMP(struct Window* win)
  293. {
  294.     int going = TRUE;
  295.     while(going)
  296.     {
  297.         struct IntuiMessage* intuimsg;
  298.         /* Wait for messages to arrive */
  299.         WaitPort(win->UserPort);
  300.         /* Messages have arrived: loop through all of them */
  301.         while(intuimsg = GT_GetIMsg(win->UserPort))
  302.         {
  303.             /* Act on this message... */
  304.             switch(intuimsg->Class)
  305.             {
  306.             case IDCMP_CLOSEWINDOW:
  307.                 going = FALSE;
  308.                 break;
  309.             case IDCMP_REFRESHWINDOW:
  310.                 /* You *MUST* remember to ask for and handle these refresh messages */
  311.                 GT_BeginRefresh(win);
  312.                 GT_EndRefresh(win, TRUE);
  313.                 break;
  314.             }
  315.             /* Reply when finished with message */
  316.             GT_ReplyIMsg(intuimsg);
  317.         }
  318.     }
  319. }
  320.  
  321.